package cn.ljlao.mall.product.goods.web;

import cn.ljlao.mall.product.goods.entity.CategoryEntity;
import cn.ljlao.mall.product.goods.service.CategoryService;
import cn.ljlao.mall.product.goods.util.RedisUtil;
import cn.ljlao.mall.product.goods.vo.Catalog2Vo;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RCountDownLatch;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @Author: LiuZhen
 * @Created: 2021/8/2 21:09
 * @Description:
 */
@Controller
@Slf4j
public class IndexController {

    @Autowired
    private  CategoryService categoryService;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RedisUtil redisUtil;


    /**
     * 首页跳转
     * @return
     */
    @GetMapping({"/","index.html","index"})
    public String indexAction (Model model){
        List<CategoryEntity> list = categoryService.getLevel1Categorys();
        model.addAttribute("categorys",list);

        return "index";
    }


    @ResponseBody
    @GetMapping("/index/catalog.json")
    public Map<String, List<Catalog2Vo>> getCatalogJson() {
        Map<String, List<Catalog2Vo>> map = categoryService.getCatalogJson();

        return map;
    }

    /**
     * 普通锁 lock
     * @return
     */
    @ResponseBody
    @GetMapping("/hello")
    public String hello() {
        //获取锁
        RLock lock = redissonClient.getLock("myLock");
        //上锁
        lock.lock();//阻塞等待

        // 加锁以后10秒钟自动解锁,无需调用unlock方法手动解锁
        //自动解锁时间一定要大于业务的执行时间。
        //lock.lock(10, TimeUnit.SECONDS);
        //锁的自动续期,业务超长,运行期间自动给锁上新的30s, 自动续期, 不用担心业务运行时间长,锁自动过期被删掉
        // 尝试加锁，最多等待100秒，上锁以后10秒自动解锁
        //boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
        try{
            log.info("加锁成功执行业务开始:......{}",Thread.currentThread().getName());
            Thread.sleep(30000);
        }catch (Exception e){

        }finally {
            log.info("解锁:......{}",Thread.currentThread().getName());
            lock.unlock();
        }
        return "hello";
    }

    /**
     * 读写锁 写锁
     * @return
     */
    @ResponseBody
    @GetMapping("/write")
    public String write() {
        RReadWriteLock lock = redissonClient.getReadWriteLock("rw_lock");//获取读写锁
        String s="";
        RLock writeLock = lock.writeLock();//获取写锁

        try {
            writeLock.lock(); // 1.改数据加写锁
            s = UUID.randomUUID().toString();
            log.info("加锁成功执行业务开始:......{}",Thread.currentThread().getName());
            Thread.sleep(30000);
            redisUtil.set("writeValue",s);
        }catch (Exception e){

        } finally {
            writeLock.unlock();
        }
        return "hello";

    }

    /**
     * 读写锁  读锁
     * @return
     */
    @ResponseBody
    @GetMapping("/read")
    public String read() {
        RReadWriteLock lock = redissonClient.getReadWriteLock("rw_lock");//获取读写锁
        RLock readLock = lock.readLock();//获取读锁
        String s="";
        try {
            readLock.lock();//上锁
            s = redisUtil.get("writeValue").toString();// 执行业务读取值
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readLock.unlock();//解锁
        }
        return s;
    }
    // 闭锁操作
    @GetMapping("/lockDoor")
    @ResponseBody
    public  String lockDoor () throws InterruptedException {
        RCountDownLatch door = redissonClient.getCountDownLatch("door");
        door.trySetCount(5);
        door.await();
        return "放假了。。。";
    }

    @GetMapping("/gogogo/{id}")
    @ResponseBody
    public String gogogo(@PathVariable("id") Long id){
        RCountDownLatch door = redissonClient.getCountDownLatch("door");
        door.countDown();
        return id+"班的人都走了";
    }




}
